﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Configuration;
using System.Windows.Forms;
using System.Data.SqlClient;
using ArcFaceSDK.Entity;
using AForge.Video.DirectShow;
using ArcFaceSDK;
using System.Threading;
using ArcFaceSDK.SDKModels;
using 图书管理系统.Entity;
using ArcFaceSDK.Utils;
using 图书管理系统.Utils;

namespace 图书管理系统
{
    public partial class RegisterFaceForm : Form
    {
        public RegisterFaceForm()
        {
            InitializeComponent();
            Load();
        }

        private void CameraLoad()
        {
            videoSourcePlayer1.VideoSource = Utils.Camera.getvideoSource();
            videoSourcePlayer1.Start();
        }

        private void CameraStop()
        {
            videoSourcePlayer1.Stop();//停止摄像头
            videoSourcePlayer1.Dispose();//释放内存
        }

        private void Load()
        {
            string strsql = "select uid from MemberInfo where facepath = '无'";
            SqlConnection con = Utils.SQLTool.GetCon();
            con.Open();
            SqlCommand cmd = con.CreateCommand();
            cmd.CommandText = strsql;
            SqlDataReader dr;
            try
            {
                dr = cmd.ExecuteReader();
                this.UidcomboBox.Items.Clear();
                while (dr.Read())
                {
                    this.UidcomboBox.Items.Add(dr["uid"]); 
                }
                dr.Close();
            }
            catch(SqlException ex)
            {
                MessageBox.Show(ex.Message);
            }
            Registerbutton.Enabled = false;
            videoSourcePlayer1.Enabled = false;
            FacetextBox.Text = "请选择已经注册基础信息的账号录入人脸信息！";
        }

        private void LoadFacepath_ToSQL(string path)
        {
            string strsql;
            string id = this.UidcomboBox.Text;
            strsql = "update MemberInfo set facepath='" + path + "'" + "where uid ='" + id + "'";
            SqlConnection con = Utils.SQLTool.GetCon();
            con.Open();
            SqlCommand cmd = con.CreateCommand();
            cmd.CommandText = strsql;
            cmd.ExecuteNonQuery();
        }

        private void UidcomboBox_SelectedIndexChanged(object sender, EventArgs e)
        {
            Registerbutton.Enabled = true;
            videoSourcePlayer1.Enabled = true;
            FacetextBox.Text = "正在为账号" + this.UidcomboBox.Text +"录入人脸信息！";
            UidcomboBox.Enabled = false;
            CameraLoad();
        }

        private void Returnbutton_Click(object sender, EventArgs e)
        {
            if(videoSourcePlayer1.VideoSource != null)
                CameraStop();
            this.Close();
        }

        private string Getimage()
        {
            if (videoSourcePlayer1.VideoSource == null)
                return null;
            Bitmap bitmap = videoSourcePlayer1.GetCurrentVideoFrame();
            string path_name = @"..\..\image\" + this.UidcomboBox.Text + ".jpg";
            bitmap.Save(path_name);
            bitmap.Dispose();
            return path_name;
        }

        private void Registerbutton_Click(object sender, EventArgs e)
        {
            string path = Getimage();
            Image srcImage = ImageUtil.ReadFromFile(path);
            Utils.FaceTool faceTool = new Utils.FaceTool();
            if (faceTool.ChooseImg(srcImage) != null)
            {
                LoadFacepath_ToSQL(path);
                MessageBox.Show("人脸录入成功！");
            }
            else
                MessageBox.Show("人脸录入失败！");
        }

        private void RegisterFaceForm_FormClosed(object sender, FormClosedEventArgs e)
        {
            if (videoSourcePlayer1.VideoSource != null)
                try
                {
                    CameraStop();
                    this.Close();
                }
                catch (Exception ex)
                {

                }
        }
        
        /// <summary>
        /// RGB摄像头Paint事件，图像显示到窗体上，得到每一帧图像，并进行处理
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void videoSource_Paint(object sender, PaintEventArgs e)
        {
            try
            {
                if (!videoSourcePlayer1.IsRunning)
                {
                    return;
                }
                //得到当前RGB摄像头下的图片
                lock (Utils.CommonInfo.rgbVideoImageLocker)
                {
                    Utils.CommonInfo.rgbVideoBitmap = videoSourcePlayer1.GetCurrentVideoFrame();
                }
                Bitmap bitmapClone = null;
                try
                {
                    lock (Utils.CommonInfo.rgbVideoImageLocker)
                    {
                        if (Utils.CommonInfo.rgbVideoBitmap == null)
                        {
                            return;
                        }
                        bitmapClone = (Bitmap)Utils.CommonInfo.rgbVideoBitmap.Clone();
                    }
                    if (bitmapClone == null)
                    {
                        return;
                    }
                    //检测人脸，得到Rect框
                    MultiFaceInfo multiFaceInfo = FaceUtil.DetectFace(Utils.Engine.videoEngine, bitmapClone);
                    //未检测到人脸
                    if (multiFaceInfo.faceNum <= 0)
                    {
                        Utils.CommonInfo.trackRGBUnitDict.ClearAllElement();
                        return;
                    }
                    Graphics g = e.Graphics;
                    float offsetX = videoSourcePlayer1.Width * 1f / bitmapClone.Width;
                    float offsetY = videoSourcePlayer1.Height * 1f / bitmapClone.Height;
                    List<int> tempIdList = new List<int>();
                    for (int faceIndex = 0; faceIndex < multiFaceInfo.faceNum; faceIndex++)
                    {
                        MRECT mrect = multiFaceInfo.faceRects[faceIndex];
                        float x = mrect.left * offsetX;
                        float width = mrect.right * offsetX - x;
                        float y = mrect.top * offsetY;
                        float height = mrect.bottom * offsetY - y;
                        int faceId = multiFaceInfo.faceID[faceIndex];
                        FaceTrackUnit currentFaceTrack = Utils.CommonInfo.trackRGBUnitDict.GetElementByKey(faceId);
                        //根据Rect进行画框
                        //将上一帧检测结果显示到页面上
                        lock (Utils.CommonInfo.rgbVideoImageLocker)
                        {
                            if (currentFaceTrack != null)
                            {
                                g.DrawRectangle(currentFaceTrack.CertifySuccess() ? Pens.Green : Pens.Red, x, y, width, height);
                                if (!string.IsNullOrWhiteSpace(currentFaceTrack.GetCombineMessage()) && x > 0 && y > 0)
                                {
                                    g.DrawString(currentFaceTrack.GetCombineMessage(), Utils.CommonInfo.font, currentFaceTrack.CertifySuccess() ? Utils.CommonInfo.greenBrush : Utils.CommonInfo.redBrush, x, y - 15);
                                }
                            }
                            else
                            {
                                g.DrawRectangle(Pens.Red, x, y, width, height);
                            }
                        }
                        if (faceId >= 0)
                        {
                            //判断faceid是否加入待处理队列
                            if (!Utils.CommonInfo.rgbFeatureTryDict.ContainsKey(faceId))
                            {
                                Utils.CommonInfo.rgbFeatureTryDict.AddDictionaryElement(faceId, 0);
                            }
                            if (!Utils.CommonInfo.rgbLivenessTryDict.ContainsKey(faceId))
                            {
                                Utils.CommonInfo.rgbLivenessTryDict.AddDictionaryElement(faceId, 0);
                            }
                            if (Utils.CommonInfo.trackRGBUnitDict.ContainsKey(faceId))
                            {
                                Utils.CommonInfo.trackRGBUnitDict.GetElementByKey(faceId).Rect = mrect;
                                Utils.CommonInfo.trackRGBUnitDict.GetElementByKey(faceId).FaceOrient = multiFaceInfo.faceOrients[faceIndex];
                            }
                            else
                            {
                                Utils.CommonInfo.trackRGBUnitDict.AddDictionaryElement(faceId, new FaceTrackUnit(faceId, mrect, multiFaceInfo.faceOrients[faceIndex]));
                            }
                            tempIdList.Add(faceId);
                        }

                    }
                    //初始化及刷新待处理队列,移除出框的人脸
                    Utils.CommonInfo.rgbFeatureTryDict.RefershElements(tempIdList);
                    Utils.CommonInfo.rgbLivenessTryDict.RefershElements(tempIdList);
                    Utils.CommonInfo.trackRGBUnitDict.RefershElements(tempIdList);
                }
                catch (Exception ee)
                {
                    LogUtil.LogInfo(GetType(), ee);
                }
                finally
                {
                    if (bitmapClone != null)
                    {
                        bitmapClone.Dispose();
                    }
                }
            }
            catch (Exception ex)
            {
                LogUtil.LogInfo(GetType(), ex);
            }
        }
        /// <summary>
        /// 摄像头播放完成事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="reason"></param>
        private void videoSource_PlayingFinished(object sender, AForge.Video.ReasonToFinishPlaying reason)
        {
            try
            {
                Control.CheckForIllegalCrossThreadCalls = false;
            }
            catch (Exception ex)
            {
                Utils.LogUtil.LogInfo(GetType(), ex);
            }
        }
    }
}
